package com.qianjing.common.filter;
import org.owasp.esapi.ESAPI;
import org.springframework.core.codec.EncodingException;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 跨站脚本和存储型XSS攻击防御工具类
 *
 * @ClassName: XssUtils
 * @CreateBy: 张占宇
 * @CreateTime: 2023年10月18日 下午15:37
 */
public class XssUtils {

    public static Pattern scriptPattern1 = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
    public static Pattern scriptPattern2 = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    public static Pattern scriptPattern3 = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    public static Pattern scriptPattern4 = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
    public static Pattern scriptPattern5 = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    public static Pattern scriptPattern6 = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    public static Pattern scriptPattern7 = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    public static Pattern scriptPattern8 = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
    public static Pattern scriptPattern9 = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
    public static Pattern scriptPattern10 = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    public static Pattern scriptPattern11 = Pattern.compile(".*<.*", Pattern.CASE_INSENSITIVE );
    public static Pattern scriptPattern12 = Pattern.compile("<.*>.*</.*>", Pattern.CASE_INSENSITIVE);


    public static String scriptXss(String value) {
        if (value != null) {

            //脚本匹配
            Matcher matcher = scriptPattern12.matcher(value);
            if (matcher.find()) {
                //截取匹配的部分
                String group = matcher.group();
                //采用OWASP ESAPI对数据输出HTML上下文中不同位置
                value = value.replace(group, owaspEsapi(group));
            }

            value = value.replaceAll("", "");
            value = scriptPattern1.matcher(value).replaceAll("");
            value = scriptPattern2.matcher(value).replaceAll("");
            value = scriptPattern3.matcher(value).replaceAll("");
            value = scriptPattern4.matcher(value).replaceAll("");
            value = scriptPattern5.matcher(value).replaceAll("");
            value = scriptPattern6.matcher(value).replaceAll("");
            value = scriptPattern7.matcher(value).replaceAll("");
            value = scriptPattern8.matcher(value).replaceAll("");
            value = scriptPattern9.matcher(value).replaceAll("");
            value = scriptPattern10.matcher(value).replaceAll("");
            value = scriptPattern11.matcher(value).replaceAll("");
        }
        return value;
    }

    /**
     * 采用OWASP ESAPI对数据输出HTML上下文中不同位置
     *
     * @param data
     * @return
     * @throws EncodingException
     */
    public static String owaspEsapi(String data){
        try {
            //HTML encode
            data = ESAPI.encoder().encodeForHTML(data);
            //HTML attribute encode
            data = ESAPI.encoder().encodeForHTMLAttribute(data);
            //JavaScript encode
            data = ESAPI.encoder().encodeForJavaScript(data);
            //CSS encode
            data = ESAPI.encoder().encodeForCSS(data);
            //URL encode
            data = ESAPI.encoder().encodeForURL(data);
        }catch (EncodingException e){

        }finally {
            return data;
        }
    }


}

